﻿using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Text;
using System.Windows.Forms;
using Gencode.Gengui.Wizzard;
using Gencode.SQLWizz.Database;
using Gencode.SQLWizz.DataType;
using System.Threading;

namespace Gencode.SQLWizz.Controls
{
    public partial class UpdateDatabase : WizzardControl
    {
		Thread queryThread;
		LogonData logData;

		/// <summary>
		/// delegate to set text ro the listbox from another thread
		/// </summary>
		/// <param name="text"></param>
		delegate void SetTextCallbackDelegate(string text);

		/// <summary>
		/// delegate to continue main thread when querythread is finished
		/// </summary>
		delegate void QueryThreadFinishedDelgate();

        public UpdateDatabase(string previousControl, string nextControl, WizzardDialog controler)
            : base(previousControl, nextControl, controler)
        {
            InitializeComponent();
        }

		public override void InitializeWizzardControl()
		{
			//base.InitializeWizzardControl();
			logData = Controler.DataObjects.GetType(typeof(LogonData)) as LogonData;
			WZUpdateDatabase updDB = new WZUpdateDatabase(logData);
			updDB.OnFinished += new QueryFinished(OnQueryFinished);
			updDB.OnError += new ErrorOccured(OnError);
			updDB.OnOutput += new OutputText(OnOutputText);
			queryThread = new Thread(updDB.UpdateDatabase);
			queryThread.Start();

			listOutput.Enabled = true;
			Controler.ButtonsEnabled = false;
			
		}

		/// <summary>
		/// will be executed by query thread when the query has finished
		/// </summary>
		private void OnQueryFinished()
		{
			if (this.InvokeRequired)
			{
				QueryThreadFinishedDelgate del = new QueryThreadFinishedDelgate(QueryThreadFinished);
				this.Invoke(del, null);

				queryThread.Abort();
			}
			else
			{
				QueryThreadFinished();
			}
		}

		/// <summary>
		/// will be executed by query thread to move to next object when finished
		/// </summary>
		private void QueryThreadFinished()
		{
			//delay
			Thread.Sleep(1500);
			//enable buttons to move to next view
			Controler.ButtonsEnabled = true;
			Controler.MoveNext();
		}

		/// <summary>
		/// displays a messagebox with the erroroutput
		/// </summary>
		/// <param name="message">message to display</param>
		/// <param name="title">title of the messagebox</param>
		private void OnError(string message, string title)
		{
			MessageBox.Show(message, title, MessageBoxButtons.OK);
		}

		private void OnOutputText(string text)
		{
			bool tmp = false;
			if (text.StartsWith("\r", false, null) || text.StartsWith("\n", false, null))
				tmp = true;

			while (tmp)
			{
				if (text.StartsWith("\r", false, null) || text.StartsWith("\n", false, null))
				{
					text = text.Substring(1);
				}
				else
					tmp = false;
			}

			//get acces to control from another thread
			if (listOutput.InvokeRequired)
			{
				// It's on a different thread, so use Invoke.
				SetTextCallbackDelegate d = new SetTextCallbackDelegate(AddText);
				this.Invoke(d, new object[] { text });
			}
			else
			{
				//if not from other thread write text normaly
				AddText(text);
			}
		}

		/// <summary>
		/// delegate method to set text form another thread
		/// </summary>
		/// <param name="text"></param>
		public void AddText(string text)
		{
			listOutput.Items.Add(text);

			listOutput.SetSelected(listOutput.Items.Count - 1, true);
			listOutput.SetSelected(listOutput.Items.Count - 1, false);
		}
    }
}
